﻿using System;
using System.Reflection;

namespace YSUtils.Assembly
{
	/// <summary>
	/// Supplies a AssemblyInfo data.
	/// </summary>
	public static class AssemblyInfoUtil
	{
		#region Properties

		/// <summary>
		/// Gets the assembly title.
		/// </summary>
		/// <value>The assembly title.</value>
		public static string AssemblyTitle
		{
			get
			{
				var attributes = GetAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
				if (attributes.Length > 0)
				{
					var titleAttribute = (AssemblyTitleAttribute)attributes[0];
					if (0 != titleAttribute.Title.Length)
					{
						return titleAttribute.Title;
					}
				}
				return System.IO.Path.GetFileNameWithoutExtension(GetAssembly().CodeBase);
			}
		}

		/// <summary>
		/// Gets the assembly version.
		/// </summary>
		/// <value>The assembly version</value>
		public static string AssemblyVersion
		{
			get
			{
				return GetAssembly().GetName().Version.ToString();
			}
		}

		/// <summary>
		/// Gets the assembly description.
		/// </summary>
		/// <value>The assembly description.</value>
		public static string AssemblyDescription
		{
			get
			{
				var attributes = GetAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);

				return (attributes.Length == 0) ? string.Empty : ((AssemblyDescriptionAttribute)attributes[0]).Description;
			}
		}

		/// <summary>
		/// Gets the assembly product name.
		/// </summary>
		/// <value>The assembly product name.</value>
		public static string AssemblyProduct
		{
			get
			{
				var attributes = GetAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);

				return (attributes.Length == 0) ? string.Empty : ((AssemblyProductAttribute)attributes[0]).Product;
			}
		}

		/// <summary>
		/// Gets the assembly copyright.
		/// </summary>
		/// <value>The assembly copyright.</value>
		public static string AssemblyCopyright
		{
			get
			{
				var attributes = GetAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);

				return (attributes.Length == 0) ? string.Empty : ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
			}
		}

		/// <summary>
		/// Gets the assembly company.
		/// </summary>
		/// <value>The assembly company.</value>
		public static string AssemblyCompany
		{
			get
			{
				var attributes = GetAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
				return (attributes.Length == 0) ? string.Empty : ((AssemblyCompanyAttribute)attributes[0]).Company;
			}
		}
		#endregion Properties

		#region Methods
		
		/// <summary>
		/// Gets the process executable in the default application domain. 
		/// In other application domains, this is the first executable that
		/// was executed by System.AppDomain.ExecuteAssembly(System.String).
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <returns>
		/// The Assembly that is the process executable in the default
		/// application domain, or the first executable that was 
		/// executed by System.AppDomain.ExecuteAssembly(System.String).
		/// </returns>
		/// <exception cref="ApplicationException">
		/// Can't get the process executable.
		/// </exception>
		private static System.Reflection.Assembly GetAssembly()
		{
			var assembly = System.Reflection.Assembly.GetEntryAssembly();

			assembly = assembly ?? System.Reflection.Assembly.GetExecutingAssembly();

			if (assembly == null)
			{
				throw new ApplicationException("Can't get the process executable.");
			}

			return assembly;
		}

		#endregion
	}
}
